use model_graph_types::{
    channel::pubsub::{Topic, TopicMessage},
    peer::get_peer_id,
};

use crate::data_channels::{message::Message, request::fire_and_forget};

use super::{create_topic, get_topic_subscribers, subscribed_topic, topic_exist};

pub async fn publish(topic: &String, subscribers: Vec<String>) -> anyhow::Result<()> {
    let peer_id = get_peer_id()?;

    create_topic(Topic::publish_topic(topic, &peer_id, subscribers)?)?;
    tracing::debug!("创建topic:{}", topic);
    //
    Ok(())
}

pub async fn publish_message(topic: &String, message: String) -> anyhow::Result<()> {
    let data = TopicMessage::new(topic, message)?;

    let request_bytes = bincode::serialize(&data)
        .map_err(|err| anyhow::anyhow!("{}", err))?
        .to_vec();

    // 判断自身是否是主题的拥有者
    if topic_exist(topic)? {
        //获取到所有的subscribers
        let subscribers = get_topic_subscribers(topic)?;

        //发送消息
        for peer_id in subscribers {
            if let Err(err) =
                fire_and_forget(&peer_id, Message::pubsub(request_bytes.clone())).await
            {
                tracing::error!("PUBSUB发送消息失败[{}]:{}-{}", peer_id, topic, err);
            }
        }
    } else {
        //判断是否是主题的订阅者
        if let Some(sub_topic) = subscribed_topic(topic)? {
            if let Err(err) =
                fire_and_forget(&sub_topic.peer_id, Message::pubsub(request_bytes.clone())).await
            {
                tracing::error!(
                    "PUBSUB发送消息失败[{}]:{}-{}",
                    sub_topic.peer_id,
                    topic,
                    err
                );
            }
        }
    }

    Ok(())
}
